import wx
import time
import os, sys
from panel.notebook import FXNoteBook
from panel.about_dialog import AboutDialog
from panel.search_dialog import SearchDialog
from panel.replace_dialog import ReplaceDialog

Version = "0.1"
ReleaseDate = "2025-01-01"

cwd = os.getcwd()  # 获取当期程序所在的路径
print(f"cwd: {cwd}")

ID_EXIT = 200
ID_ABOUT = 201
ID_NEW = 202
ID_OPEN = 203
ID_OPEN_DIR = 204
ID_SAVE = 205
ID_SAVE_AS = 206
ID_UNDO = 207
ID_CUT = 208
ID_COPY = 209
ID_PASTE = 210
ID_DELETE = 211
ID_FIND = 212
ID_FIND_NEXT = 213
ID_REPLACE = 214
ID_SELECT_ALL = 215


class MainFrame(wx.Frame):
    def __init__(self, parent, id, title):
        wx.Frame.__init__(self, parent, id, title, size=(640, 480))

        # 工具图标的实现
        self.setup_icon()
        # 菜单栏的创建
        # self.setup_menu_bar()
        self.create_menu_bar()
        # UI界面
        self.init_ui()
        # 状态栏的创建
        self.setup_status_bar()
        self.Bind(wx.EVT_CLOSE, self.OnCloseWindow)


    def setup_icon(self):
        # 图标的实现
        self.img_path = os.path.abspath(cwd + "\\icons\\calculator.png")  # \--转义符
        # self.img_path = os.path.abspath("icons/calculator.png")
        icon = wx.Icon(self.img_path, type=wx.BITMAP_TYPE_PNG)
        self.SetIcon(icon)

    # temp 临时方案
    def setup_menu_bar(self):
        # 菜单栏
        menubar = wx.MenuBar()
        # 菜单：文件（File）
        file_menu = wx.Menu()
        # 菜单项：新建功能
        new_menu = wx.MenuItem(file_menu, ID_NEW, "新建(N)", "new file")
        new_menu.SetBitmap(wx.Bitmap(cwd + "\\icons\\new.png"))
        file_menu.Append(new_menu)
        self.Bind(wx.EVT_MENU, self.OnNewFile, new_menu)
        # 菜单项：打开功能
        open_menu = wx.MenuItem(file_menu, ID_OPEN, "打开(O)", "open file")
        open_menu.SetBitmap(wx.Bitmap(cwd + "\\icons\\open.png"))
        file_menu.Append(open_menu)
        self.Bind(wx.EVT_MENU, self.OnOpen, id=ID_OPEN)
        # 菜单项：保存功能
        save_menu = wx.MenuItem(file_menu, ID_SAVE, "保存(S)", "save file")
        save_menu.SetBitmap(wx.Bitmap(cwd + "\\icons\\save.png"))
        file_menu.Append(save_menu)
        self.Bind(wx.EVT_MENU, self.OnSave, id=ID_SAVE)
        # 分割线
        file_menu.AppendSeparator()
        # 菜单项：退出功能
        quit_menu = wx.MenuItem(file_menu, ID_EXIT, "退出(Q)", "quit")
        quit_menu.SetBitmap(wx.Bitmap(cwd + "\\icons\\quit.png"))
        file_menu.Append(quit_menu)
        self.Bind(wx.EVT_MENU, self.OnQuit, id=ID_EXIT)
        # 将菜单添加到文件(File)中
        menubar.Append(file_menu, "文件(File)")
        # -----------------------------------------------------------------------------
        # 菜单：编辑（Edit）
        edit_menu = wx.Menu()
        # 菜单项：撤销功能
        undo_menu = wx.MenuItem(edit_menu, ID_UNDO, "撤销(U)", "undo")
        undo_menu.SetBitmap(wx.Bitmap(cwd + "\\icons\\undo.png"))
        edit_menu.Append(undo_menu)
        self.Bind(wx.EVT_MENU, self.OnUndo, id=ID_UNDO)

        # 分割线
        edit_menu.AppendSeparator()
        # 菜单项：剪切功能
        cut_menu = wx.MenuItem(edit_menu, ID_CUT, "剪切(T)", "cut")
        cut_menu.SetBitmap(wx.Bitmap(cwd + "\\icons\\cut.png"))
        edit_menu.Append(cut_menu)
        self.Bind(wx.EVT_MENU, self.OnCut, id=ID_CUT)
        # self.Bind(wx.EVT_MENU, self.OnCut, id=ID_CUT)  gugu
        # 菜单项：复制功能
        copy_menu = wx.MenuItem(edit_menu, ID_COPY, "复制(C)", "copy")
        copy_menu.SetBitmap(wx.Bitmap(cwd + "\\icons\\copy.png"))
        edit_menu.Append(copy_menu)
        self.Bind(wx.EVT_MENU, self.OnCopy, id=ID_COPY)

        # self.Bind(wx.EVT_MENU, self.OnCopy, id=ID_COPY)
        # 菜单项：粘贴功能
        paste_menu = wx.MenuItem(edit_menu, ID_PASTE, "粘贴(P)", "paste")
        paste_menu.SetBitmap(wx.Bitmap(cwd + "\\icons\\paste.png"))
        edit_menu.Append(paste_menu)
        self.Bind(wx.EVT_MENU, self.OnPaste, id=ID_PASTE)

        # self.Bind(wx.EVT_MENU, self.OnPaste, id=ID_PASTE)
        # 菜单项：删除功能
        delete_menu = wx.MenuItem(edit_menu, ID_DELETE, "删除(D)", "delete")
        delete_menu.SetBitmap(wx.Bitmap(cwd + "\\icons\\delete.png"))
        edit_menu.Append(delete_menu)
        self.Bind(wx.EVT_MENU, self.OnClear, id=ID_DELETE)

        # self.Bind(wx.EVT_MENU, self.OnDelete, id=ID_DELETE)
        # 分割线
        edit_menu.AppendSeparator()
        # 菜单项：查找功能
        find_menu = wx.MenuItem(edit_menu, ID_FIND, "查找(F)", "find")
        find_menu.SetBitmap(wx.Bitmap(cwd + "\\icons\\find.png"))
        edit_menu.Append(find_menu)
        self.Bind(wx.EVT_MENU, self.OnFind, id=ID_FIND)
        # 菜单项：查找下一个功能
        find_next_menu = wx.MenuItem(edit_menu, ID_FIND_NEXT, "查找下一个(N)", "find next")
        find_next_menu.SetBitmap(wx.Bitmap(cwd + "\\icons\\find_next.png"))
        edit_menu.Append(find_next_menu)
        # self.Bind(wx.EVT_MENU, self.OnFindNext, id=ID_FIND_NEXT)
        # 菜单项：替换功能
        replace_menu = wx.MenuItem(edit_menu, ID_REPLACE, "替换(R)", "replace")
        replace_menu.SetBitmap(wx.Bitmap(cwd + "\\icons\\replace.png"))
        edit_menu.Append(replace_menu)
        # self.Bind(wx.EVT_MENU, self.OnReplace, id=ID_REPLACE)
        # 分割线
        edit_menu.AppendSeparator()
        # 菜单项：全选功能
        select_all_menu = wx.MenuItem(edit_menu, ID_SELECT_ALL, "全选(A)", "select all")
        select_all_menu.SetBitmap(wx.Bitmap(cwd + "\\icons\\select_all.png"))
        edit_menu.Append(select_all_menu)
        self.Bind(wx.EVT_MENU, self.OnSelectAll, id=ID_SELECT_ALL)
        # 将菜单添加到编辑(Edit)中
        menubar.Append(edit_menu, "编辑(Edit)")
        # ------------------------------------------------------------------------------
        # 菜單：关于（About）
        help_menu = wx.Menu()
        about_menu = wx.MenuItem(help_menu, ID_ABOUT, "关于(A)", "About application")
        about_menu.SetBitmap(wx.Bitmap(cwd + "\\icons\\about.png"))
        help_menu.Append(about_menu)
        self.Bind(wx.EVT_MENU, self.OnMenuAbout, id=ID_ABOUT)

        menubar.Append(help_menu, "帮助(Help)")
        # ----------------------------------------------------------------------
        self.Bind(wx.EVT_CLOSE, self.OnCloseWindow)
        self.SetMenuBar(menubar)

    def init_ui(self):
        # 面板的显示
        self.fxnotebook = FXNoteBook(self, -1)
        self.finddlg = None
        self.finddata = wx.FindReplaceData()  # 。wx.FindReplaceData 是 wxPython 库中的一个类，用于存储查找和替换对话框的数据。
        # Bind
        self.Bind(wx.EVT_FIND, self.on_find)
        self.Bind(wx.EVT_FIND_NEXT, self.on_find)
        self.Bind(wx.EVT_FIND_REPLACE, self.on_replace)
        self.Bind(wx.EVT_FIND_REPLACE_ALL, self.on_replace_all)
        self.Bind(wx.EVT_FIND_CLOSE, self.on_find_close)
        self.Bind(wx.EVT_CLOSE, self.OnQuit)

    def _InitFindDialog(self, mode):
        if self.finddlg:
            self.finddlg.Destroy()
            style = (wx.FR_NOUPDOWN | wx.FR_NOMATCHCASE | wx.FR_NOWHOLEWORD)
            # wx.FR_NOUPDOWN：禁用查找对话框中的上下文按钮。
            # wx.FR_NOMATCHCASE：禁用区分大小写的匹配选项。
            # wx.FR_NOWHOLEWORD：禁用仅匹配整个单词的选项
        if mode == ID_REPLACE:
            style = (wx.FR_NOUPDOWN | wx.FR_NOMATCHCASE | wx.FR_NOWHOLEWORD | wx.FR_REPLACEDIALOG)
            dlg = wx.FindReplaceDialog(self, self.finddata, "替换", style)
            self.finddlg = dlg
        else:
            dlg = wx.FindReplaceDialog(self, self.finddata, "查找", style=0)
            self.finddlg = dlg

    def OnClear(self, event):
        # Clear select text
        print("clear")
        start, end = self.fxnotebook.text_panel.text_result.GetSelection()
        self.fxnotebook.text_panel.text_result.Remove(start, end)
        self.fxnotebook.text_panel.text_result.Refresh()
        event.Skip()
        print("over")

    def setup_status_bar(self):
        self.status_bar = self.CreateStatusBar(3)
        self.status_bar.SetStatusWidths([-2, -2, -1])  # 状态栏的比例
        self.status_bar.SetStatusText("Ready", 0)  # 设置状态栏[0]文本
        self.status_bar.SetStatusText("", 1)  # 设置状态栏[0]文本
        # Timer
        self.timer = wx.PyTimer(self.Notify)
        self.timer.Start(1000, wx.TIMER_CONTINUOUS)  # wx.TIMER_CONTINUOUS: 一直跑
        self.Notify()
    # 状态栏中时间显示格式
    def Notify(self):
        time_local = time.localtime(time.time())
        strf_time_local = time.strftime("%Y-%m-%d %H:%M:%S", time_local)
        self.status_bar.SetStatusText(strf_time_local, 2)

    # ---------------------------------Menu Start---------------------------------------
    # 集成菜单功能
    def OnMenu(self, event):
        ID_MENU_ITEM = (ID_NEW, ID_OPEN, ID_SAVE, ID_SAVE_AS, ID_EXIT,
                        ID_UNDO, ID_CUT, ID_COPY, ID_PASTE, ID_DELETE,
                        ID_FIND, ID_FIND_NEXT, ID_REPLACE, ID_SELECT_ALL,
                        ID_ABOUT)
        event_id = event.GetId()
        if event_id in ID_MENU_ITEM:
            if event_id == ID_NEW:  # 新建文件
                self.OnNewFile(event)
                self.fxnotebook.text_panel.text_result.Refresh()
                event.Skip()  # event.Skip() 是 wxPython 中用于事件处理的方法，它允许当前事件处理器完成其操作后，继续将事件传递给其他事件处理器。如果不调用 event.Skip()，则事件会在当前处理器中被“消耗”，不再传递给其他处理器。
            elif event_id == ID_OPEN:  # 打开文件
                self.OnOpen(event)
            elif event_id == ID_SAVE:
                self.OnSave(event)
            elif event_id == ID_SAVE_AS:
                print("另存为")
                # self.OnSaveAs(event)
            elif event_id == ID_EXIT:
                self.OnQuit(event)
            elif event_id == ID_UNDO:  # 撤销
                self.fxnotebook.text_panel.text_result.Undo()
                event.Skip()
            elif event_id == ID_CUT:  # 剪切
                self.fxnotebook.text_panel.text_result.Cut()
                event.Skip()
            elif event_id == ID_COPY:  # 复制
                self.OnCopy(event)
            elif event_id == ID_PASTE:  # 粘贴
                self.OnPaste(event)
            elif event_id == ID_DELETE:  # 删除
                print("Delete")
                start, end = self.fxnotebook.text_panel.text_result.GetSelection()
                self.fxnotebook.text_panel.text_result.Remove(start, end)
                self.fxnotebook.text_panel.text_result.Refresh()
                event.Skip()
            elif event_id == ID_FIND:  # 查找
                self.OnFind(event)
            elif event_id == ID_FIND_NEXT:  # 查找下一个
                self.OnFindNext(event)
            elif event_id == ID_REPLACE:  # 替换
                self.OnReplace(event)
            elif event_id == ID_SELECT_ALL:  # 全选
                self.OnSelectAll(event)
            elif event_id == ID_ABOUT:
                self.OnMenuAbout(event)
            else:
                event.Skip()
    # -------------------------菜单项处理函数Handler Start-------------------------------
    # 新建文件
    def OnNewFile(self, event):
        if not self.fxnotebook.text_panel.text_result.IsEmpty():
            dlg = wx.MessageDialog(self, "是否将更改保存到无标题文件？", "记事本",
                                   wx.YES_NO | wx.CANCEL | wx.ICON_QUESTION)
            ret_code = dlg.ShowModal()
            if ret_code == wx.ID_YES:  # 保存 and 另存为 gugu
                self.OnSave(event)
                # 保存完后，创建新的文件
                self.fxnotebook.text_panel.text_result.SetValue("")
            elif ret_code == wx.ID_NO:  # 清空
                self.fxnotebook.text_panel.text_result.SetValue("")
            else:  # 取消
                dlg.Close()
            dlg.Destroy()
    # 打开选择文件的dialog
    def OnOpen(self, event):
        print("Open")
        self.dirname = ""
        filesFilter = "Text Files (*.txt)|*.txt|Python (*.py)|*.py|All Files (*.*)|*.*"
        dlg = wx.FileDialog(self, "Choose a file", self.dirname, "", wildcard=filesFilter, style=wx.FD_OPEN)
        if dlg.ShowModal() == wx.ID_OK:
            self.filename = dlg.GetFilename()
            path = dlg.GetPath()
            with open(path, "rb") as f:
                self.fxnotebook.text_panel.text_result.SetValue(f.read().decode('utf-8'))
                self.file = path
        dlg.Destroy()
        """
        if dlg.ShowModal() == wx.ID_OK:
            self.filename = dlg.GetFilename()
            self.dirname = dlg.GetDirectory()
            f = open(os.path.join(self.dirname, self.filename), "r")
            self.fxnotebook.text_panel.text_result.SetValue(f.read().encode('utf-8'))
            f.close()
        dlg.Destroy()
        """
        # self.fxnotebook.text_panel.text_result.SetFocus()
        wx.StaticText(self.status_bar, label="文件名：" + self.filename + ", 共 " + str(
            self.fxnotebook.text_panel.text_result.GetNumberOfLines()) + " 行", pos=(0, 1))
        self.fxnotebook.text_panel.text_result.Refresh()
        event.Skip()
        print("over")
    # 保存文件
    def OnSave(self, event):
        # 判断是否有内容
        if self.fxnotebook.text_panel.text_result.IsEmpty():
            return
        self.dirname = ""
        filesFilter = "Text Files (*.txt)|*.txt|Python (*.py)|*.py|All Files (*.*)|*.*"
        dlg = wx.FileDialog(self, "Choose a file", self.dirname, "", wildcard=filesFilter, style=wx.FD_SAVE)
        if dlg.ShowModal() == wx.ID_OK:
            self.filename = dlg.GetFilename()
            self.dirname = dlg.GetDirectory()
            f = open(os.path.join(self.dirname, self.filename), "w")
            f.write(self.fxnotebook.text_panel.text_result.GetValue())
            f.close()
        dlg.Destroy()
        # 重新设置记事本的Title
        self.Title = self.filename + " - 记事本"
    # 退出
    def OnQuit(self, event):
        self.Close()
    def OnUndo(self, event):
        # Undo select text
        print("undo")
        self.fxnotebook.text_panel.text_result.Undo()
        event.Skip()
        print("over")
    def OnCut(self, event):
        # Cut select text
        print("cut")
        self.fxnotebook.text_panel.text_result.Cut()
        event.Skip()
        print("over")
    def OnCopy(self, event):
        # Copy select text
        print("copy")
        self.text_obj = wx.TextDataObject()  # 文本框的对象
        self.text_obj.SetText(self.fxnotebook.text_panel.text_result.GetStringSelection().decode('utf-8'))
        if wx.TheClipboard.IsOpened() or wx.TheClipboard.Open():
            wx.TheClipboard.SetData(self.text_obj)
            wx.TheClipboard.Close()
        else:
            wx.MessageBox("Unable to open the clipboard", "Error")
        self.fxnotebook.text_panel.text_result.Refresh()
        event.Skip()
        print("over")
    def OnPaste(self, event):
        # Paste select text
        print("paste")
        self.text_obj = wx.TextDataObject()
        if wx.TheClipboard.IsOpened() or wx.TheClipboard.Open():
            if wx.TheClipboard.GetData(self.text_obj):
                self.fxnotebook.text_panel.text_result.GetInsertionPoint()
                self.fxnotebook.text_panel.text_result.SetValue(self.text_obj.GetText().encode('utf-8'))
            wx.TheClipboard.Close()
        self.fxnotebook.text_panel.text_result.Refresh()
        event.Skip()
        print("over")
    # lesson——15
    # 查找功能
    def OnFind(self, event):
        event_id = event.GetId()
        print(f"OnFind, ID:{event_id}")
        if event_id in {ID_FIND, }:
            self._InitFindDialog(event_id)
            self.finddlg.Show()
        else:
            event.Skip()
        print("Over")
    def OnFindNext(self, event):
        event_id = event.GetId()
        print(f"OnFindNext, ID:{event_id}")
        if event_id in {ID_FIND_NEXT, }:
            self._InitFindDialog(event_id)
            self.finddlg.Show()
        else:
            event.Skip()
        print("Over")
    def OnReplace(self, event):
        event_id = event.GetId()
        print(f"OnReplace, ID:{event_id}")
        if event_id in {ID_REPLACE, }:
            self._InitFindDialog(event_id)
            self.finddlg.Show()
        else:
            event.Skip()
        print("Over")
    def OnSelectAll(self, event):
        print("select all")
        self.fxnotebook.text_panel.text_result.SelectAll()
        event.Skip()
        print("over")
    def OnMenuAbout(self, event):
        dlg = AboutDialog(None, -1)
        dlg.ShowModal()
        dlg.Destroy()
        self.fxnotebook.text_panel.text_result.Refresh()
        event.Skip()
    # 关闭应用程序
    def OnCloseWindow(self, event):
        self.Destroy()
        event.Skip()
    # -------------------------菜单项处理函数Handler End-------------------------------
    # =========================功能的具体实现 Start======================================
    # lesson_16--5:06
    def DoOpen(self, event):
        """Open a file"""
        print("和 OnOpen 同理")
    def DoSaveAs(self):
        """Show SaveAs dialog"""
        filesFilter = "Text Files (*.txt)|*.txt|Python (*.py)|*.py|All Files (*.*)|*.*"
        dlg = wx.FileDialog(self, "另存为...", wildcard=filesFilter, style=wx.FD_SAVE|wx.FD_OVERWRITE_PROMPT)
        if dlg.ShowModal() == wx.ID_OK:
            path = dlg.GetPath()
            self.Save(path)
            self.file = path
        self.fxnotebook.text_panel.text_result.SetModified(False)
        dlg.Destroy()
    def Save(self, path):
        """Save the file"""
        with open(path, "w") as f:
            text = self.fxnotebook.text_panel.text_result.GetValue()
            f.write(text)
            self.fxnotebook.text_panel.text_result.SetModified(False)
    def on_find(self, event):
        # find text
        find_str = self.finddata.GetFindString()
        if not self.FindString(find_str):
            wx.Bell()
            message = "没有查找到你需要的内容,\n\n或者已经到了文本的头或尾"
            style = wx.YES_NO | wx.ICON_WARNING | wx.CENTER
            wx.MessageBox(message, "查找结果提示？", style)
    def on_replace(self, event):
        # Replace text
        self.fxnotebook.text_panel.text_result.GetInsertionPoint()
        replace_str = self.finddata.GetReplaceString()
        find_str = self.finddata.GetFindString()
        self.fxnotebook.text_panel.text_result.SetInsertionPoint(0)
        cur_pos = self.fxnotebook.text_panel.text_result.GetInsertionPoint()
        start, end = cur_pos, cur_pos
        if find_str:
            if self.FindString(find_str):
                start, end = self.fxnotebook.text_panel.text_result.GetSelection()
            self.fxnotebook.text_panel.text_result.Replace(start, end, replace_str)
    def on_replace_all(self, event):
        # Replace all text
        replace_str = self.finddata.GetReplaceString()
        find_str = self.finddata.GetFindString()
        text = self.fxnotebook.text_panel.text_result.GetValue()
        new_text = text.replace(find_str, replace_str)
        self.fxnotebook.text_panel.text_result.SetValue(new_text)
    def on_find_close(self, event):
        if self.finddlg:
            self.finddlg.Destroy()
            self.finddlg = None
    def FindString(self, find_str):
        # Find find_str in TextCtrl and set selection
        text = self.fxnotebook.text_panel.text_result.GetValue()
        cur_sel = self.fxnotebook.text_panel.text_result.GetSelection()
        if cur_sel[0] != cur_sel[1]:
            cur_pos = max(cur_sel)
        else:
            cur_pos = self.fxnotebook.text_panel.text_result.GetInsertionPoint()
        if cur_pos == self.fxnotebook.text_panel.text_result.GetLastPosition():
            cur_pos = 0
        # 注释Comment
        text = text.upper()
        find_str = find_str.upper()
        found = text.find(find_str, cur_pos)
        if found != -1:
            end = found + len(find_str)
            self.fxnotebook.text_panel.text_result.SetSelection(end, found)
            self.fxnotebook.text_panel.text_result.SetFocus()
            return True
        return False

    # =========================功能的具体实现 End========================================
    # 菜单数据
    def menuData(self):
        return (("文件(&F)", ("新建(&N)", ID_NEW, cwd + "\\icons\\new.png", self.OnMenu),
                 ("打开(&O)", ID_OPEN, cwd + "\\icons\\open.png", self.OnMenu),
                 ("保存(&S)", ID_SAVE, cwd + "\\icons\\save.png", self.OnMenu),
                 ("另存为(&A)", ID_SAVE_AS, cwd + "\\icons\\save.png", self.OnMenu),
                 ("", "", "", ""),
                 ("退出(&Q)", ID_EXIT, cwd + "\\icons\\quit.png", self.OnMenu),
                 ),
                ("编辑(&E)", ("撤销(&U)", ID_UNDO, cwd + "\\icons\\undo.png", self.OnMenu),
                 ("剪切(&T)", ID_CUT, cwd + "\\icons\\cut.png", self.OnMenu),
                 ("复制(&C)", ID_COPY, cwd + "\\icons\\copy.png", self.OnMenu),
                 ("粘贴(&P)", ID_PASTE, cwd + "\\icons\\paste.png", self.OnMenu),
                 ("删除(&L)", ID_DELETE, cwd + "\\icons\\delete.png", self.OnMenu),
                 ("", "", "", ""),
                 ("查找(&F)", ID_FIND, cwd + "\\icons\\find.png", self.OnMenu),
                 ("查找下一个(&N)", ID_FIND_NEXT, cwd + "\\icons\\find_next.png", self.OnMenu),
                 ("替换(&R)", ID_REPLACE, cwd + "\\icons\\replace.png", self.OnMenu),
                 ("全选(&A)", ID_SELECT_ALL, cwd + "\\icons\\select_all.png", self.OnMenu),
                 ),
                ("帮助(&H)", ("关于(&A)", ID_ABOUT, cwd + "\\icons\\about.png", self.OnMenu)),
                )

    # 创建菜单栏并显示菜单
    def create_menu_bar(self):
        menu_bar = wx.MenuBar()
        for each_menu_data in self.menuData():
            menu_label = each_menu_data[0]
            menu_items = each_menu_data[1:]
            menu_bar.Append(self.create_menu_item(menu_items), menu_label)
        self.SetMenuBar(menu_bar)

    # 创建菜单项
    def create_menu_item(self, menu_items):
        menu = wx.Menu()
        for each_label, each_id, each_icon, each_handler in menu_items:
            if not each_label:
                menu.AppendSeparator()
                continue
            menu_item = wx.MenuItem(menu, each_id, each_label)
            menu_item.SetBitmap(wx.Bitmap(each_icon))
            menu.AppendItem(menu_item)
            self.Bind(wx.EVT_MENU, each_handler, menu_item)
        return menu
    # ---------------------------------Menu End---------------------------------------


class App(wx.App):
    def __init__(self):
        super(self.__class__, self).__init__()
        # wx.App.__init__(self)
        self.title = None
        self.version = None

    def OnInit(self):
        self.version = "lesson_14：简易記事本三"
        self.title = "wxPython初级教程之" + self.version
        self.frame = MainFrame(None, -1, self.title)
        self.frame.Show(True)

        return True


if __name__ == "__main__":
    app = App()
    app.MainLoop()  # 启动主事件循环后，持续检查是否有事件需要处理，处理事件并更新界面，直到应用程序关闭。
